<script>
import Hls from 'hls.js';
import Artplayer from 'artplayer'
import artplayerPluginHlsControl from 'artplayer-plugin-hls-control';
import ProcessItem from "@/views/video/ProcessItem.vue";
import {proxy} from "@/api/task";
import ws from "@/utils/wservice";

export default {
  name: "VideoView2",
  components: {ProcessItem},
  data() {
    return {
      art: '',
      url: this.$route.query.url,
      proxy: {
        url: '',
        taskId: '',
        userId: this.$route.query.userId,
        state: 0,
        process: 0,
        socket: undefined,
      },
      play: {
        state: true
      }
    }
  },
  methods: {
    startArt() {
      this.art = new Artplayer({
        container: '.artplayer-app',
        poster: 'https://ss.zlzblog.com:30999/gh4riovd/source/back.png',
        url: '',
        lang: 'zh-cn',
        fullscreen: true,
        pip: true,
        playbackRate: true,
        subtitleOffset: true,
        hotkey: true,
        fastForward: true,
        autoOrientation: true,
        setting: true,
        plugins: [
          artplayerPluginHlsControl({
            quality: {
              control: true,
              setting: true,
              getName: (level) => level.height + 'P',
              // I18n
              title: '视频质量',
              auto: '自动',
            },
          }),
        ],
        customType: {
          m3u8: function playM3u8(video, url, art) {
            if (Hls.isSupported()) {
              if (art.hls) art.hls.destroy();
              // let retryTimes = 0;
              const hls = new Hls();
              hls.config.fragLoadPolicy.default.errorRetry = {
                maxNumRetry: 0,
                retryDelayMs: 1000,
                maxRetryDelayMs: 15000,
                backoff: 'exponential',
              }
              hls.loadSource(url);
              hls.attachMedia(video);
              hls.on(Hls.Events.MEDIA_ATTACHED, () => {
                art.poster = ''
                hls.on(Hls.Events.ERROR, (event, data) => {
                  if (data.fatal) {
                    switch (data.type) {
                      case Hls.ErrorTypes.NETWORK_ERROR:
                        setTimeout(() => {
                          // if(retryTimes >= 5){
                          //   art.notice.show = '视频缓冲失败请等待或点击刷新按钮重试';
                          // }
                          hls.startLoad()
                          // retryTimes++;
                        }, 1000)
                        break;
                      case Hls.ErrorTypes.MEDIA_ERROR:
                        hls.recoverMediaError();
                        break;
                      default:
                        // cannot recover
                        hls.destroy();
                        break;
                    }
                  }
                });
              });
              art.hls = hls;
              art.on('destroy', () => hls.destroy());
            } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
              video.src = url;
            } else {
              art.notice.show = 'Unsupported playback format: m3u8';
            }
          }
        },
      });
      this.art.setting.add({
        html: '服务器解析播放',
        tooltip: '解析',
        icon: `<img width="22" heigth="22" src="${require('@/assets/parse.svg')}">`,
        style: {},
        switch: true,
        onSwitch: (item) => {
          const nextState = !item.switch;
          this.play.state = nextState
          item.tooltip = nextState ? '解析' : '源站';
          this.art.notice.show = '已切换' + item.tooltip + '播放'
          this.playVideo(this.art.seek)
          return nextState;
        },
      });
    },
    addControl(state) {
      if (!state && this.art.controls.cache.has('进度条')) {
        this.art.controls.remove('进度条')
        return
      }
      if (this.art.controls.cache.has('进度条')) {
        return;
      }
      let control = {
        name: '进度条',
        html: document.getElementById('processDom'),
        position: 'right',
        tooltip: '服务器缓存进度',
        click: () => {
          this.art.notice.show = this.proxy.process + "% 已缓存"
        }
      }
      this.art.controls.add(control)
    },
    playVideo(currentTime) {
      // 解析播放
      if (this.play.state) {
        proxy(this.url, this.proxy.userId).then(res => {
          this.proxy.url = res.data.url
          this.proxy.taskId = res.data.taskId
          this.addControl(true)
          this.startSocket(true)
          this.art.url = this.proxy.url
          if (currentTime) {
            this.art.seek = currentTime
          }
        })
        return
      }
      this.art.url = this.url
      this.addControl(false)
      this.startSocket(false)
      if (currentTime) {
        this.art.seek = currentTime
      }
    },
    startSocket(open) {
      if (!open) {
        this.proxy.socket.close()
        return
      }
      this.proxy.socket = ws(this.proxy.userId, this.proxy.taskId)
      // Set up event listeners
      this.proxy.socket.onopen = (event) => {
        console.log('WebSocket connection opened.');
        this.updateState(event.data)
      };
      this.proxy.socket.onmessage = (event) => {
        this.updateState(event.data)
      };

      this.proxy.socket.onerror = (error) => {
        console.error('WebSocket Error:', error);
      };

      this.proxy.socket.onclose = () => {
        console.log('WebSocket connection closed.');
      };
    },
    updateState(res) {
      if (!res) {
        return;
      }
      // 0 等待 1 缓存中 2完成
      res = JSON.parse(res)
      console.log(res)
      if (res.code === 2) {
        this.startSocket(false)
        this.addControl(false)
        return
      }
      if (res.code === 1) {
        let min = res.data.minCode - 10000
        let max = res.data.maxCode - 10000
        this.proxy.process = (min * 100 / max).toFixed(2) + ''
      }
    }
  },
  mounted() {
    this.startArt()
    this.playVideo()
  }

}
</script>

<template>
  <div class="content">
    <div class="artplayer-app"/>
    <ProcessItem v-if="play.state" :process="proxy.process" id="processDom"/>
  </div>
</template>

<style scoped>
content, .artplayer-app {
  position: relative;
  height: 100%;
  width: 100%;
}
</style>